"""
KidsBuddy 1.0 API端点
定义系统的API接口和处理逻辑
"""

import time
from typing import Dict, List, Any, Optional, Callable
from pathlib import Path
import json
import asyncio

from ..config.settings import LOG_DIR
from ..core.hardware_state_machine import HardwareCommand, CommandPriority
from ..utils.helpers import generate_unique_id, format_timestamp
from .schemas import format_api_response, validate_session_id, validate_student_id


class ApiHandler:
    """API处理器类"""
    
    def __init__(self, supervision_system=None):
        """
        初始化API处理器
        
        Args:
            supervision_system: 监督系统实例
        """
        self.supervision_system = supervision_system
    
    async def handle_request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理API请求
        
        Args:
            endpoint: API端点名称
            params: 请求参数
            
        Returns:
            API响应
        """
        # 查找对应的处理器
        handler = getattr(self, f"handle_{endpoint}", None)
        
        if not handler or not callable(handler):
            return format_api_response(
                success=False,
                message=f"未知的API端点: {endpoint}",
                errors=["ENDPOINT_NOT_FOUND"]
            )
        
        try:
            # 调用对应的处理器
            return await handler(params)
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"API处理错误: {str(e)}",
                errors=[str(e)]
            )
    
    async def handle_system_status(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        获取系统状态
        
        Args:
            params: 请求参数
            
        Returns:
            系统状态响应
        """
        if not self.supervision_system:
            return format_api_response(
                success=False,
                message="监督系统未初始化",
                errors=["SYSTEM_NOT_INITIALIZED"]
            )
        
        status = self.supervision_system.get_system_status()
        
        return format_api_response(
            success=True,
            message="获取系统状态成功",
            data=status
        )
    
    async def handle_start_session(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        启动监督会话
        
        Args:
            params: 请求参数
                - student_id: 学生ID
                - camera_source: 摄像头ID (可选，默认为0)
            
        Returns:
            会话启动响应
        """
        if not self.supervision_system:
            return format_api_response(
                success=False,
                message="监督系统未初始化",
                errors=["SYSTEM_NOT_INITIALIZED"]
            )
        
        # 验证参数
        student_id = params.get("student_id")
        if not student_id or not validate_student_id(student_id):
            return format_api_response(
                success=False,
                message="无效的学生ID",
                errors=["INVALID_STUDENT_ID"]
            )
        
        camera_source = params.get("camera_source", 0)
        
        # 如果系统已在运行，返回错误
        if self.supervision_system.get_system_status().get("running", False):
            return format_api_response(
                success=False,
                message="监督系统已在运行中",
                errors=["SYSTEM_ALREADY_RUNNING"]
            )
        
        # 启动会话
        try:
            await self.supervision_system.start(student_id=student_id, camera_source=camera_source)
            
            # 获取更新后的状态
            status = self.supervision_system.get_system_status()
            
            return format_api_response(
                success=True,
                message="监督会话已启动",
                data={
                    "session_id": status.get("current_session"),
                    "system_status": status
                }
            )
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"启动会话失败: {str(e)}",
                errors=[str(e)]
            )
    
    async def handle_stop_session(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        停止监督会话
        
        Args:
            params: 请求参数
                - session_id: 会话ID (可选)
            
        Returns:
            会话停止响应
        """
        if not self.supervision_system:
            return format_api_response(
                success=False,
                message="监督系统未初始化",
                errors=["SYSTEM_NOT_INITIALIZED"]
            )
        
        # 验证会话ID（如果提供）
        session_id = params.get("session_id")
        if session_id and not validate_session_id(session_id):
            return format_api_response(
                success=False,
                message="无效的会话ID",
                errors=["INVALID_SESSION_ID"]
            )
        
        # 获取当前会话ID
        current_session = self.supervision_system.get_system_status().get("current_session")
        
        # 如果提供了会话ID，但与当前会话不匹配
        if session_id and current_session and session_id != current_session:
            return format_api_response(
                success=False,
                message="提供的会话ID与当前会话不匹配",
                errors=["SESSION_ID_MISMATCH"]
            )
        
        # 如果系统未运行，返回错误
        if not self.supervision_system.get_system_status().get("running", False):
            return format_api_response(
                success=False,
                message="监督系统未运行",
                errors=["SYSTEM_NOT_RUNNING"]
            )
        
        # 停止会话
        try:
            await self.supervision_system.shutdown()
            
            return format_api_response(
                success=True,
                message="监督会话已停止",
                data={
                    "session_id": current_session,
                    "stopped_at": format_timestamp(time.time())
                }
            )
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"停止会话失败: {str(e)}",
                errors=[str(e)]
            )
    
    async def handle_get_session_stats(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        获取会话统计
        
        Args:
            params: 请求参数
                - session_id: 会话ID
            
        Returns:
            会话统计响应
        """
        if not self.supervision_system:
            return format_api_response(
                success=False,
                message="监督系统未初始化",
                errors=["SYSTEM_NOT_INITIALIZED"]
            )
        
        # 验证会话ID
        session_id = params.get("session_id")
        if not session_id or not validate_session_id(session_id):
            return format_api_response(
                success=False,
                message="无效的会话ID",
                errors=["INVALID_SESSION_ID"]
            )
        
        # 获取会话统计
        try:
            # 这里假设time_series_recorder可以通过supervision_system访问
            recorder = self.supervision_system.time_series_recorder
            stats = recorder.get_session_statistics(session_id)
            
            return format_api_response(
                success=True,
                message="获取会话统计成功",
                data=stats
            )
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"获取会话统计失败: {str(e)}",
                errors=[str(e)]
            )
    
    async def handle_send_command(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        发送硬件命令
        
        Args:
            params: 请求参数
                - command_type: 命令类型
                - priority: 优先级 (可选，默认为NORMAL)
                - payload: 命令数据
            
        Returns:
            命令发送响应
        """
        if not self.supervision_system:
            return format_api_response(
                success=False,
                message="监督系统未初始化",
                errors=["SYSTEM_NOT_INITIALIZED"]
            )
        
        # 验证参数
        command_type = params.get("command_type")
        if not command_type:
            return format_api_response(
                success=False,
                message="未提供命令类型",
                errors=["MISSING_COMMAND_TYPE"]
            )
        
        # 获取优先级
        priority_str = params.get("priority", "NORMAL")
        try:
            priority = getattr(CommandPriority, priority_str.upper())
        except (AttributeError, ValueError):
            return format_api_response(
                success=False,
                message=f"无效的优先级: {priority_str}",
                errors=["INVALID_PRIORITY"]
            )
        
        # 获取数据
        payload = params.get("payload", {})
        
        # 创建命令
        command = HardwareCommand(
            command_id=generate_unique_id("api_cmd"),
            command_type=command_type,
            priority=priority,
            payload=payload,
            timestamp=time.time()
        )
        
        # 发送命令
        try:
            await self.supervision_system.hardware_state_machine.command_queue.add_command(command)
            
            return format_api_response(
                success=True,
                message="命令已发送",
                data={
                    "command_id": command.command_id,
                    "command_type": command.command_type,
                    "priority": priority_str.upper(),
                    "sent_at": format_timestamp(command.timestamp)
                }
            )
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"发送命令失败: {str(e)}",
                errors=[str(e)]
            )
    
    async def handle_get_logs(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        获取日志
        
        Args:
            params: 请求参数
                - lines: 返回的行数 (可选，默认为100)
                - level: 日志级别 (可选)
            
        Returns:
            日志响应
        """
        # 获取参数
        lines = int(params.get("lines", 100))
        level = params.get("level")
        
        try:
            # 查找最新的日志文件
            log_dir = Path(LOG_DIR)
            log_files = list(log_dir.glob("kidsbuddy_*.log"))
            
            if not log_files:
                return format_api_response(
                    success=False,
                    message="未找到日志文件",
                    errors=["NO_LOG_FILES"]
                )
            
            # 按修改时间排序，获取最新的日志文件
            latest_log = sorted(log_files, key=lambda f: f.stat().st_mtime, reverse=True)[0]
            
            # 读取日志
            with open(latest_log, 'r', encoding='utf-8') as f:
                all_lines = f.readlines()
            
            # 过滤日志级别（如果提供）
            if level:
                filtered_lines = [line for line in all_lines if f"| {level.upper()}" in line]
            else:
                filtered_lines = all_lines
            
            # 获取指定行数
            log_lines = filtered_lines[-lines:] if lines > 0 else filtered_lines
            
            return format_api_response(
                success=True,
                message="获取日志成功",
                data={
                    "log_file": str(latest_log),
                    "total_lines": len(all_lines),
                    "filtered_lines": len(filtered_lines),
                    "returned_lines": len(log_lines),
                    "logs": log_lines
                }
            )
        except Exception as e:
            return format_api_response(
                success=False,
                message=f"获取日志失败: {str(e)}",
                errors=[str(e)]
            )